<?php
///////////////////////////////////////////////////////////////////////////////////////////////////////
//  这个文件是 JCAT PHP框架的一部，该项目和此文件 均遵循 GNU 自由软件协议
// 
//  Copyleft 2008 JeCat.cn(http://team.JeCat.cn)
//
//
//  JCAT PHP框架 的正式全名是：Jellicle Cat PHP Framework。
//  “Jellicle Cat”出自 Andrew Lloyd Webber的音乐剧《猫》（《Prologue:Jellicle Songs for Jellicle Cats》）。
//  JCAT 是一个开源项目，它像音乐剧中的猫一样自由，你可以毫无顾忌地使用JCAT PHP框架。JCAT 由中国团队开发维护。
//  正在使用的这个版本是：0.4.1 / SVN信息: $Id: class.JCAT_DBSQLCreateMySQL.php 1510 2009-03-23 06:51:00Z alee $
//
//
//
//  相关的链接：
//    [主页] http://jcat.JeCat.cn
//    [下载(HTTP)] http://code.google.com/p/jcat-php/downloads/list
//    [下载(svn)] svn checkout http://jcat-php.googlecode.com/svn/branches/0.4.0/Framework/ JCAT0.4
//    [在线文档] http://jcat.JeCat.cn/document
//    [社区] http://jj.jecat.cn/forum-7-1.html
//  不很相关：
//    [MP3] http://www.google.com/search?q=jellicle+songs+for+jellicle+cats+Andrew+Lloyd+Webber
//    [VCD/DVD] http://www.google.com/search?q=CAT+Andrew+Lloyd+Webber+video
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*-- Project Introduce --*/





/**
 * What's this Class ?
 *
 * @author		alee
 * @access		public
 * @last		2007.12.6
 */
class JCAT_DBSQLCreateMySQL extends JCAT_DBSQLCreate
{	
	const CURRENT_TIMESTAMP = 'CURRENT_TIMESTAMP' ; 
	
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$sEngine
	 * @return	void
	 */
	public function SetEngine($sEngine)
	{
		if( !in_array($sEngine,self::$arrTableEngine) )
		{
			throw new JCAT_Exception(JCAT_Language::SentenceEx(
				'正在设置无效的数据库引擎：%s'
				, 'JCAT', null
				, $sEngine
			)) ;
		}
		
		$this->sEngine = $sEngine ;
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @return	string
	 */
	public function GetEngine()
	{
		return $this->sEngine ;
	}
	
	/**
	 * 设置对象属性 sCharset
	 *
	 * @access	public
	 * @param	$sCharset		string	table's charset
	 * @return	void
	 */
	public function SetCharset($sCharset)
	{
		$this->sCharset = $sCharset ;
	}
	
	/**
	 * 取得对象属性 sCharset
	 *
	 * @access	public
	 * @return	string
	 */
	public function GetCharset()
	{
		return $this->sCharset ;
	}

	
	/**
	 * 设置对象属性 sComment
	 *
	 * @access	public
	 * @param	$sComment		string	table's comment
	 * @return	void
	 */
	public function SetComment($sComment)
	{
		$this->sComment = $sComment ;
	}
	
	/**
	 * 取得对象属性 sComment
	 *
	 * @access	public
	 * @return	string
	 */
	public function GetComment()
	{
		return $this->sComment ;
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$sClmName
	 * @param	$sClmType
	 * @param	$nLength
	 * @param	$sValue
	 * @param	$arrOption
	 * 
	 * @return	void
	 */
	public function AddColumn($sClmName,$sInputClmType,$nLength,$sValue='',$nFlag=0,$arrOption=array())
	{
		$sClmType = strtoupper($sInputClmType) ;
		if( !in_array($sClmType,self::$arrColumnFields) )
		{
			throw new JCAT_Exception(JCAT_Language::SentenceEx(
				'字段：%s 使用了无效的类型：%'
				, 'JCAT', null
				, $sClmName, $sClmType
			)) ;
		}
		
		return parent::AddColumn($sClmName,$sClmType,$nLength,$sValue,$nFlag,$arrOption) ;
	}
	
	
	/**
	 * 创建并返回SQL语句
	 * 
	 * @access	public
	 * @return	string
	 */
	public function MakeSQL()
	{
		$sTable = $this->GetTable() ;
		$sSQL = "CREATE TABLE `{$sTable}` (" ;
		
		// column list
		$arrClmSQL = array() ;
		$aIterator = $this->CreateColumnIterator() ;
		for ( $aIterator->First(); !$aIterator->IsDone(); $aIterator->Next() )
		{
			$arrClm = $aIterator->Current() ;
			$arrClmSQL[] = $this->MakeSQLColumn($arrClm) ;
		}
		
		// make column index
		$arrClmSQL = array_merge($arrClmSQL,$this->MakeSQLIndex()) ; 
		
		// make column and index
		$sSQL.= implode(",\r\n",$arrClmSQL) ;
		
		// table attrute
		$sSQL.= $this->MakeSQLTableAttrubite() ;
		
		return $sSQL ;
	}
	
/*

`ddd` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`eee` VARCHAR( 12 ) NOT NULL ,
`hhh` VARCHAR( 12 ) NOT NULL ,
`jjj` ENUM( '1', '0' ) NOT NULL ,
`kkk` VARCHAR( 1 ) NOT NULL
) ENGINE = InnoDB CHARACTER SET armscii8 COLLATE armscii8_general_ci COMMENT = 'xxxxxx' 

CREATE TABLE `EPDataset_uid_17`.`fffffffffff` (
`x` VARCHAR( 6 ) BINARY NOT NULL DEFAULT '1',
`y` INT( 6 ) UNSIGNED NOT NULL ,
`c` INT( 6 ) UNSIGNED ZEROFILL NOT NULL ,
`e` VARCHAR( 6 ) CHARACTER SET armscii8 COLLATE armscii8_bin NOT NULL COMMENT 'xxxx',
FULLTEXT (
`e`
)
) ENGINE = MYISAM

 CREATE TABLE `EPDataset_uid_17`.`ssf` (
`ddd` VARCHAR( 13 ) NOT NULL
) ENGINE = InnoDB CHARACTER SET armscii8 COLLATE armscii8_general_ci COMMENT = 'dddddddddddddd' 
*/		
	/**
	 * Description
	 *
	 * @access	public
	 * @return	string
	 */
	public function MakeSQLIndex()
	{
		$arrIndexed = array() ;
		
		$aIterator = $this->CreateIndexIterator() ;
		for ( $aIterator->First(); !$aIterator->IsDone(); $aIterator->Next() )
		{
			$arrIndex = $aIterator->Current();
			
			JCAT_ASSERT::ASSERT_(isset(self::$arrIndexString[$arrIndex['type']]));
			$sTypeString = self::$arrIndexString[$arrIndex['type']] ;
			$sClms = implode('`,`',$arrIndex['columns']) ;
			$arrIndexed[] = "{$sTypeString} `{$arrIndex['name']}` (`{$sClms}`)" ;
		}
		
		return $arrIndexed ;
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @return	string
	 */
	public function MakeSQLTableAttrubite()
	{
		$sSQL = ") ENGINE = ". $this->GetEngine() ;
		
		// charset
		$sTableCharset = $this->GetCharset() ;
		if( $sTableCharset )
		{
			$sCharsetString = self::MakeSQLCharsetSting($sTableCharset) ;
			if( $sCharsetString===null )
			{
				throw new JCAT_Exception(JCAT_Language::SentenceEx(
					'字段%s被指定了意外的字符集：%s'
					, 'JCAT', null
					, $arrCml['name'], $arrCml['charset']
				)) ;
			}
			
			$sSQL.= ' '.$sCharsetString ;
		}
		
		// comment
		$sTableComment = $this->GetComment() ;
		if( $sTableComment )
		{
			$sTableComment = addcslashes($sTableComment) ;
			$sSQL.= " COMMENT '{$sTableComment}'" ;
		}
		
		return $sSQL ;
	}
	
	/**
	 * Description
	 *
	 * @access	private
	 * @param	$arrCml	array
	 * @return	string
	 */
	private function MakeSQLColumn(array $arrCml)
	{
		// column name and type
		$sSQL = "`{$arrCml['name']}` {$arrCml['type']}" ;
		
		// column length 
		if( !in_array($arrCml['type'],self::$arrNeedlessLengthType) )
		{
			if( $arrCml['length']===null )
			{
				$arrCml['length'] = 10 ;
			}
			$sSQL.= "( {$arrCml['length']} )" ; 
		}
		
		// column flag
		$sSQL.= $this->MakeSQLFlags($arrCml['flag']) ;

		// default value
		if( $arrCml['default']!==null )
		{
			$sSQL.= " DEFAULT '{$arrCml['default']}'" ;
		}
		
		// comment
		if( isset($arrCml['comment']) )
		{
			$sComment = addcslashes($arrCml['comment']) ;
			$sSQL.= " COMMENT '{$sComment}'" ;
		}
		
		// charset
		if( isset($arrCml['charset']) )
		{
			$sCharsetString = self::MakeSQLCharsetSting($arrCml['charset']) ;
			if( $sCharsetString===null )
			{
				throw new JCAT_Exception(JCAT_Language::SentenceEx(
					'字段%s被指定了意外的字符集：%s'
					, 'JCAT', null
					, $arrCml['name'], $arrCml['charset']
				)) ;
			}
			
			$sSQL.= ' '.$sCharsetString ;
		}
		
		return $sSQL ;
	}
		
		
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$sCharsetCollate		string
	 * @static
	 * @return	string
	 */
	static public function MakeSQLCharsetSting($sCharsetCollate)
	{
		if( !isset(self::$arrCharsetCollate[$sCharsetCollate]) )
		{
			return  null ;
		}
		
		$sCharset = self::$arrCharsetCollate[$sCharsetCollate] ;
		return "CHARACTER SET {$sCharset} COLLATE {$sCharsetCollate}" ;
	}

	// 属性 ///////////////////////////////////////////////////////////////////////////////
	
		
	const VARCHAR = 'VARCHAR' ;
	const TINYINT = 'TINYINT' ;
	const TEXT = 'TEXT' ;
	const DATE = 'DATE' ;
	const SMALLINT = 'SMALLINT' ;
	const MEDIUMINT = 'MEDIUMINT' ;
	const INT = 'INT' ;
	const BIGINT = 'BIGINT' ;
	const FLOAT = 'FLOAT' ;
	const DOUBLE = 'DOUBLE' ;
	const DECIMAL = 'DECIMAL' ;
	const DATETIME = 'DATETIME' ;
	const TIMESTAMP = 'TIMESTAMP' ;
	const TIME = 'TIME' ;
	const YEAR = 'YEAR' ;
	const CHAR = 'CHAR' ;
	const TINYBLOB = 'TINYBLOB' ;
	const TINYTEXT = 'TINYTEXT' ;
	const BLOB = 'BLOB' ;
	const MEDIUMBLOB = 'MEDIUMBLOB' ;
	const MEDIUMTEXT = 'MEDIUMTEXT' ;
	const LONGBLOB = 'LONGBLOB' ;
	const LONGTEXT = 'LONGTEXT' ;
	const ENUM = 'ENUM' ;
	const SET = 'SET' ;
	const BIT = 'BIT' ;
	const BOOL = 'BOOL' ;
	const BINARY = 'BINARY' ;
	const VARBINARY = 'VARBINARY' ;
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @static
	 * @var		array
	 */
	static private $arrNeedlessLengthType = array(
		self::DATE
		, self::DATETIME
		, self::TIMESTAMP
		, self::TIME
		, self::YEAR
		, self::TINYBLOB
		, self::TINYTEXT
		, self::BLOB
		, self::MEDIUMBLOB
		, self::MEDIUMTEXT
		, self::LONGBLOB
		, self::LONGTEXT
		, self::TEXT
	) ;
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @static
	 * @var		array
	 */
	static private $arrCharsetCollate = array(
							'armscii8_bin'=>'armscii8'
							, 'armscii8_general_ci'=>'armscii8'
							
							, 'ascii_bin'=>'ascii'
							, 'ascii_general_ci'=>'ascii'
							
							, 'big5_bin'=>'big5'
							, 'big5_chinese_ci'=>'big5'
							
							, 'binary' => 'binary'
							
							, 'cp1250_bin'=>'cp1250'
							, 'cp1250_croatian_ci'=>'cp1250'
							, 'cp1250_czech_cs'=>'cp1250'
							, 'cp1250_general_ci'=>'cp1250'
							
							, 'cp1251_bin'=>'cp1251'
							, 'cp1251_bulgarian_ci'=>'cp1251'
							, 'cp1251_general_ci'=>'cp1251'
							, 'cp1251_general_cs'=>'cp1251'
							, 'cp1251_ukrainian_ci'=>'cp1251'
							
							, 'cp1256_bin'=>'cp1256'
							, 'cp1256_general_ci'=>'cp1256'
							, 'cp1257_bin'=>'cp1257'
							, 'cp1257_general_ci'=>'cp1257'
							, 'cp1257_lithuanian_ci'=>'cp1257'
							
							, 'cp850_bin'=>'cp850'
							, 'cp850_general_ci'=>'cp850'
							
							, 'cp852_bin'=>'cp852'
							, 'cp852_general_ci'=>'cp852'
							
							, 'cp866_bin'=>'cp866'
							, 'cp866_general_ci'=>'cp866'
							
							, 'cp932_bin'=>'cp932'
							, 'cp932_japanese_ci'=>'cp932'
							
							, 'dec8_bin'=>'dec8'
							, 'dec8_swedish_ci'=>'dec8'
							
							, 'eucjpms_bin'=>'eucjpms'
							, 'eucjpms_japanese_ci'=>'eucjpms'
							
							, 'euckr_bin'=>'euckr'
							, 'euckr_korean_ci'=>'euckr'
							
							, 'gb2312_bin'=>'gb2312'
							, 'gb2312_chinese_ci'=>'gb2312'
							, 'gbk_bin'=>'gbk'
							, 'gbk_chinese_ci'=>'gbk'
							
							, 'geostd8_bin'=>'geostd8'
							, 'geostd8_general_ci'=>'geostd8'
							
							, 'greek_bin'=>'greek'
							, 'greek_general_ci'=>'greek'
							
							, 'hebrew_bin'=>'hebrew'
							, 'hebrew_general_ci'=>'hebrew'
							
							, 'hp8_bin'=>'hp8'
							, 'hp8_english_ci'=>'hp8'
							
							, 'keybcs2_bin'=>'keybcs2'
							, 'keybcs2_general_ci'=>'keybcs2'
							
							, 'koi8r_bin'=>'koi8r'
							, 'koi8r_general_ci'=>'koi8r'
							
							, 'koi8u_bin'=>'koi8u'
							, 'koi8u_general_ci'=>'koi8u'
							
							, 'latin1_bin'=>'latin1'
							, 'latin1_danish_ci'=>'latin1'
							
							, 'latin1_general_ci'=>'latin1'
							, 'latin1_general_cs'=>'latin1'
							, 'latin1_german1_ci'=>'latin1'
							, 'latin1_german2_ci'=>'latin1'
							, 'latin1_spanish_ci'=>'latin1'
							, 'latin1_swedish_ci'=>'latin1'
							
							, 'latin2_bin'=>'latin2'
							, 'latin2_croatian_ci'=>'latin2'
							, 'latin2_czech_cs'=>'latin2'
							, 'latin2_general_ci'=>'latin2'
							, 'latin2_hungarian_ci'=>'latin2'
							
							, 'latin5_bin'=>'latin5'
							, 'latin5_turkish_ci'=>'latin5'
							
							, 'latin7_bin'=>'latin7'
							, 'latin7_estonian_cs'=>'latin7'
							, 'latin7_general_ci'=>'latin7'
							, 'latin7_general_cs'=>'latin7'
							
							, 'macce_bin'=>'macce'
							, 'macce_general_ci'=>'macce'
							
							, 'macroman_bin'=>'macroman'
							, 'macroman_general_ci'=>'macroman'
							
							, 'sjis_bin'=>'sjis'
							, 'sjis_japanese_ci'=>'sjis'
							
							, 'swe7_bin'=>'swe7'
							, 'swe7_swedish_ci'=>'swe7'
							
							, 'tis620_bin'=>'tis620'
							, 'tis620_thai_ci'=>'tis620'
							
							, 'ucs2_bin'=>'ucs2'
							, 'ucs2_czech_ci'=>'ucs2'
							, 'ucs2_danish_ci'=>'ucs2'
							
							, 'ucs2_esperanto_ci'=>'ucs2'
							, 'ucs2_estonian_ci'=>'ucs2'
							, 'ucs2_general_ci'=>'ucs2'
							, 'ucs2_hungarian_ci'=>'ucs2'
							, 'ucs2_icelandic_ci'=>'ucs2'
							, 'ucs2_latvian_ci'=>'ucs2'
							, 'ucs2_lithuanian_ci'=>'ucs2'
							, 'ucs2_persian_ci'=>'ucs2'
							, 'ucs2_polish_ci'=>'ucs2'
							, 'ucs2_roman_ci'=>'ucs2'
							, 'ucs2_romanian_ci'=>'ucs2'
							, 'ucs2_slovak_ci'=>'ucs2'
							, 'ucs2_slovenian_ci'=>'ucs2'
							, 'ucs2_spanish2_ci'=>'ucs2'
							, 'ucs2_spanish_ci'=>'ucs2'
							, 'ucs2_swedish_ci'=>'ucs2'
							, 'ucs2_turkish_ci'=>'ucs2'
							, 'ucs2_unicode_ci'=>'ucs2'
							
							, 'ujis_bin'=>'ujis'
							, 'ujis_japanese_ci'=>'ujis'
							
							, 'utf8_bin'=>'utf8'
							, 'utf8_czech_ci'=>'utf8'
							, 'utf8_danish_ci'=>'utf8'
							, 'utf8_esperanto_ci'=>'utf8'
							, 'utf8_estonian_ci'=>'utf8'
							, 'utf8_general_ci'=>'utf8'
							, 'utf8_hungarian_ci'=>'utf8'
							, 'utf8_icelandic_ci'=>'utf8'
							, 'utf8_latvian_ci'=>'utf8'
							, 'utf8_lithuanian_ci'=>'utf8'
							, 'utf8_persian_ci'=>'utf8'
							, 'utf8_polish_ci'=>'utf8'
							, 'utf8_roman_ci'=>'utf8'
							, 'utf8_romanian_ci'=>'utf8'
							, 'utf8_slovak_ci'=>'utf8'
							, 'utf8_slovenian_ci'=>'utf8'
							, 'utf8_spanish2_ci'=>'utf8'
							, 'utf8_spanish_ci'=>'utf8'
							, 'utf8_swedish_ci'=>'utf8'
							, 'utf8_turkish_ci'=>'utf8'
							, 'utf8_unicode_ci'=>'utf8'
	);

	
	
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @static
	 * @var		array
	 */
	static private $arrColumnFields = array(
					'VARCHAR'
					, 'TINYINT'
					, 'TEXT'
					, 'DATE'
					, 'SMALLINT'
					, 'MEDIUMINT'
					, 'INT'
					, 'BIGINT'
					, 'FLOAT'
					, 'DOUBLE'
					, 'DECIMAL'
					, 'DATETIME'
					, 'TIMESTAMP'
					, 'TIME'
					, 'YEAR'
					, 'CHAR'
					, 'TINYBLOB'
					, 'TINYTEXT'
					, 'BLOB'
					, 'MEDIUMBLOB'
					, 'MEDIUMTEXT'
					, 'LONGBLOB'
					, 'LONGTEXT'
					, 'ENUM'
					, 'SET'
					, 'BIT'
					, 'BOOL'
					, 'BINARY'
					, 'VARBINARY'
	) ;

	/**
	 * Description
	 * 
	 * @access	private
	 * @static
	 * @var		array
	 */
	static private $arrTableEngine = array(
        'MyISAM'
        , 'MEMORY'
        , 'InnoDB'
        , 'BLACKHOLE'
        , 'ARCHIVE'
        , 'CSV'
        , 'FEDERATED'
        , 'MRG_MYISAM'
	) ;
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @var		string
	 */
	private $sEngine = 'MyISAM' ;
	
	
	/**
	 * 对象属性 sCharset
	 * 
	 * @access	private
	 * @var		string
	 */
	private $sCharset ;
	
	/**
	 * 对象属性 sComment
	 * 
	 * @access	private
	 * @var		string
	 */
	private $sComment ;
	
	
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @static
	 * @var		array
	 */
	static private $arrIndexString = array(
			'PRIMARY' => 'PRIMARY KEY'
			, 'INDEX' => 'KEY'
			, 'UNIQUE' => 'UNIQUE KEY'
			, 'FULLTEXT' => 'FULLTEXT KEY'
	) ;
}
?>